#pragma once
#include "md5_tokens.h"

#include <string>
#include <deque>
#include <vector>

namespace krryn{
namespace data{
	class md5_lexer_exception{};
	class md5_lexer_eof : public md5_lexer_exception{};

	class md5_lexer{
	public:
		typedef md5_token store_t;

		md5_lexer(const std::string &a_Filename);

		// Notice that the contents of the md5_token returned,
		// specifically the m_String member is only valid
		// for as long as this md5_lexer instance exists!
		md5_token scan();
		unsigned int line();
	private:
		typedef std::vector<std::string> parts_t;
		
		std::vector<std::string> m_Keywords;
		size_t m_BufferPos;
        std::vector<char> m_Buffer;
		unsigned int m_LineNumber;

		core::owned_string read_lexeme();

		md5_token tokenize(core::owned_string a_String);
		md5_token make(md5_tags a_Tag, core::owned_string a_Value);
		md5_token make_keyword(core::owned_string a_Value);

		// we may want to refactor this into a helper class, these functions 
		// feel too generic for this class
		bool is_real(core::owned_string a_String);
		bool is_integer(core::owned_string a_String);
		bool has_sign(core::owned_string a_String);

		bool is_keyword(core::owned_string a_String);
	};
}
}